package com.ybt.message.unpack.impl;

import java.util.List;

import org.apache.log4j.Logger;
import org.jdom.Document;
import org.jdom.Element;

import com.ruleengine.context.IContextProperty;
import com.ruleengine.context.IWorkflowConext;
import com.ruleengine.context.impl.ContextPropertyFactory;
import com.sinosoft.midplat.common.JdomUtil;
import com.ybt.message.constant.FixedLengthConstants;
import com.ybt.message.unpack.IMessageUnpack;
import com.ybt.message.unpack.MessageUnpackDecorator;
import com.ybt.message.unpack.exception.MessageUnpackException;

/**
 * 定长报文解析类. <br/>此类并非传统意义上的定长报文解析。是为了适应 目前银保通现有报文转换模块而做的一种变通而已。
 * 
 * @author AB033862 Jul 31, 2012
 */
public class FixedLengthUnpack extends MessageUnpackDecorator {
    private static Logger logger = Logger.getLogger(FixedLengthUnpack.class);

    public FixedLengthUnpack(IMessageUnpack unpack) {
        super(unpack);
    }

    public Object unpackMessage(IWorkflowConext context, Object msg)
            throws MessageUnpackException {
        // TODO Auto-generated method stub
        byte[] message = (byte[])msg;
        try {
            // 字节编码
            String encode = config.getAttributeValue(
                    FixedLengthConstants.ARRT_TAG_ENCODE);
            // 报文体
            Document result = null;
            List<Element> items = config.getChildren(
                    FixedLengthConstants.ELE_TAG_ITEM);
            for (Element ie : items) {
                // 解析每个定长字段

                // 定长偏移量
                int start = Integer
                        .parseInt(ie
                                .getAttributeValue(FixedLengthConstants.ARRT_TAG_START));
                // 字段长度
                String strLength = ie
                        .getAttributeValue(FixedLengthConstants.ARRT_TAG_LENGTH);
                int length = message.length - start;
                if (strLength != null) {
                    length = Integer.parseInt(strLength);
                }
                // 字段类型
                String type = ie
                        .getAttributeValue(FixedLengthConstants.ARRT_TAG_TYPE);
                // 字段别名，即context中的key
                String alias = ie
                        .getAttributeValue(FixedLengthConstants.ARRT_TAG_ALIAS);

                // 拷贝字段内容
                byte[] content = new byte[length];
                System.arraycopy(message, start, content, 0, length);

                if (alias != null) {
                    // 别名不为空，则全部放入context中
                    String fun = new String(content, encode);
                    IContextProperty<String> tranPro = ContextPropertyFactory
                            .getInstance().createSerializeVariable(alias);
                    tranPro.setValue(fun);
                    context.setContextProperty(tranPro);
                    logger.debug("unpack the item [" + alias+":"+fun+"]");
                } else if (FixedLengthConstants.ARRT_VALUE_XML.equals(type)) {
                    // 报文体
                    logger.debug("unpack the message body : " + new String(content, encode));
                    result = JdomUtil.build(content, encode);
                }
            }
            return result;
        } catch (Exception e) {
            throw new MessageUnpackException(e);
        }
    }

}
